`timescale 1ms / 1ms  //定义时间颗粒度
module tb();
    reg rst, clk;     //定义时钟和复位信号
    reg [11:0] pc_1, pc_2;
    wire [11:0] pc_1_IF, pc_2_IF, pc_1_ID, pc_2_ID, pc_1_OP, pc_2_OP, pc_1_SCH, pc_2_SCH, pc_1_EXE, pc_2_EXE;
    wire [31:0] X, Y;
    reg [4:0] rob_no_in;
    wire [31:0] result;
    wire [4:0] rob_no_out;
    //指令存储器中读取到两条指令
    wire [31:0] inst_1, inst_2, inst_1_id, inst_2_id;
    wire [31:0] share_buffer;

    //规定iverilog的生成文件和制定模块，如果使用其他构建工具，此块内容删掉即可
    initial begin            
        $dumpfile("tb.vcd");        //生成的vcd文件名称
        $dumpvars(0, tb);     //tb模块名称
    end

    //生成时钟信号，每10ns跳变一次
    initial begin
        rst = 0;
        clk = 0;
        forever begin
            #10 clk = ~clk;
        end
    end

    //在开始给一个复位信号
    initial begin
        #10
        rst = 1;

        #20 
        rst = 0;
    end

    // initial begin
    //     //pc累加
    //     #10
    //     pc_1 = 0;
    //     pc_2 = 0;
    //     forever begin
    //         #20
    //         pc_1 = pc_1 + 2;
    //         pc_2 = pc_2 + 2;
    //     end
    // end

    initial begin
        #30
        //生成PC信号
        pc_1 = 0;
        pc_2 = 1;
        forever begin
            #20
            pc_1 = pc_1 + 2;
            pc_2 = pc_2 + 2;
        end
    end

    //操作数的信号
    wire opt_x_1_ready, opt_y_1_ready, opt_x_2_ready, opt_y_2_ready, opt_x_1_ready_sch, opt_y_1_ready_sch, opt_x_2_ready_sch, opt_y_2_ready_sch;
    wire [31:0] opt_x_1_value, opt_y_1_value, opt_x_2_value, opt_y_2_value, opt_x_1_value_sch, opt_y_1_value_sch, opt_x_2_value_sch, opt_y_2_value_sch;
    wire [4:0] opt_x_1_rob, opt_y_1_rob, opt_x_2_rob, opt_y_2_rob, opt_x_1_rob_sch, opt_y_1_rob_sch, opt_x_2_rob_sch, opt_y_2_rob_sch;
    //原始寄存器号和映射过后的寄存器号
    wire [4:0] rs_1, rs_2, rt_1, rt_2, rd_1, rd_2, rs_1_op, rs_2_op, rt_1_op, rt_2_op, rd_1_op, rd_2_op;
    wire [5:0] rs_1_mp, rs_2_mp, rt_1_mp, rt_2_mp, rd_1_mp, rd_2_mp;
    //寄存器是否准备好的的信号
    wire rs_1_ready, rt_1_ready, rs_2_ready, rt_2_ready, rs_1_ready_sch, rt_1_ready_sch, rs_2_ready_sch, rt_2_ready_sch;
    //寄存器的值
    wire [31:0] rs_1_value, rt_1_value, rs_2_value, rt_2_value, rs_1_value_sch, rt_1_value_sch, rs_2_value_sch, rt_2_value_sch;
    //逻辑寄存器号
    wire [4:0] rd_1_logic, rd_2_logic;
    //rob写入使能
    wire rob_write_en_1, rob_write_en_2, rob_write_en_1_op, rob_write_en_2_op;
    wire [1:0] rob_write_sel_1, rob_write_sel_2, rob_write_sel_1_op, rob_write_sel_2_op;
    //译码器得到的运算控制信号
    wire [3:0] alu_ctrl_1, alu_ctrl_2, alu_ctrl_1_sch, alu_ctrl_2_sch;
    wire [3:0] complex_ctrl_1, complex_ctrl_2, complex_ctrl_1_sch, complex_ctrl_2_sch;
    

    //运算器数据选择信号
    wire alu_a_sel_1, alu_b_sel_1, alu_a_sel_2, alu_b_sel_2, alu_a_sel_1_id, alu_b_sel_1_id, alu_a_sel_2_id, alu_b_sel_2_id, alu_a_sel_1_op, alu_b_sel_1_op, alu_a_sel_2_op, alu_b_sel_2_op;
    //运算模式信号
    wire [2:0] work_mode_1, work_mode_2, work_mode_1_op, work_mode_2_op, work_mode_1_sch, work_mode_2_sch; 
    //立即数扩充后的输出
    wire [31:0] imm_out_1, imm_out_2, imm_1_sch, imm_2_sch;
    //源寄存器对应的ROB号
    wire [4:0] rs_1_rob, rt_1_rob, rs_2_rob, rt_2_rob, rd_1_rob, rd_2_rob, rs_1_rob_sch, rt_1_rob_sch, rs_2_rob_sch, rt_2_rob_sch, rd_1_rob_sch, rd_2_rob_sch;
    wire rd_1_rob_flag_op, rd_2_rob_flag_op, rd_1_rob_flag_sch, rd_2_rob_flag_sch;
    //立即数直接写回ROB的控制信号
    wire rob_save_direct_ctrl_1, rob_save_direct_ctrl_2, rob_save_direct_ctrl_1_op, rob_save_direct_ctrl_2_op;
    //数据存储器的控制信号
    wire [2:0] dm_rd_ctrl_1, dm_rd_ctrl_2, dm_rd_ctrl_1_op, dm_rd_ctrl_2_op, dm_rd_ctrl_1_sch, dm_rd_ctrl_1_mem, dm_rd_ctrl_2_sch, dm_rd_ctrl_2_mem;
    wire [1:0] dm_wr_ctrl_1, dm_wr_ctrl_2, dm_wr_ctrl_1_op, dm_wr_ctrl_2_op, dm_wr_ctrl_1_sch, dm_wr_ctrl_1_mem, dm_wr_ctrl_2_sch, dm_wr_ctrl_2_mem;
    
    //输出到存储单元的访存信号
    wire [31:0] address_x_1, address_y_1, address_x_2, address_y_2;
    wire [3:0] address_ctrl_1, address_ctrl_2;
    wire address_ready_en_1, address_ready_en_2;
    wire [4:0] address_save_no_1, address_save_no_2, address_rob_no_1, address_rob_no_2;
    wire [31:0] mem_address_1, mem_content_1, mem_address_2, mem_content_2;
    wire [2:0] mem_rd_ctrl_1, mem_rd_ctrl_2;
    wire [1:0] mem_wr_ctrl_1, mem_wr_ctrl_2;
    wire mem_read_en_1, mem_write_en_1, mem_read_en_2, mem_write_en_2;
    wire [4:0] mem_save_no_1, mem_save_no_2, mem_rob_no_1, mem_rob_no_2;


    //保留站输出的运算单元的控制信号
    //普通运算
    wire alu_ready_en_1, alu_ready_en_2;
    wire [31:0] alu_x_1, alu_x_2, alu_y_1, alu_y_2;
    wire [4:0] alu_save_no_1, alu_save_no_2, alu_rob_no_1, alu_rob_no_2;
    wire [3:0] cAlu_ctrl_1, cAlu_ctrl_2;
    wire alu_done_1, alu_done_2;
    wire [4:0] alu_commit_rob_no_1, alu_commit_rob_no_2, alu_commit_save_no_1, alu_commit_save_no_2;
    wire [31:0] alu_commit_value_1, alu_commit_value_2;
    //乘法
    wire complex_ready_en_1, complex_ready_en_2;
    wire [31:0] complex_x_1, complex_x_2, complex_y_1, complex_y_2;
    wire [4:0] complex_save_no_1, complex_save_no_2, complex_rob_no_1, complex_rob_no_2;
    wire [3:0] cComplex_ctrl_1, cComplex_ctrl_2;
    wire mul_done_1, mul_done_2;
    wire [4:0] mul_commit_rob_no_1, mul_commit_rob_no_2, mul_commit_save_no_1, mul_commit_save_no_2;
    wire [31:0] mul_commit_value_1, mul_commit_value_2;


    //访存需要用到的一些信号
    wire read_en_mem, write_en_mem;             //RAM读写使能信号
    wire [2:0] dm_rd_ctrl_mem;
    wire [1:0] dm_wr_ctrl_mem;
    wire [31:0] dm_addr_mem, dm_din_mem;
    wire [4:0] save_no_mem;
    wire [4:0] rd_rob_no_mem;

    //保存到保留站的使能信号
    wire save_en_1, save_en_2;

    
    //测试信号
    wire load_over;

    

    //规定时钟总长
    initial
        #5000 $finish;

    // always @(posedge load_over) begin
    //     //指令加载完毕后, 重置一下PC
    //     pc_1 = -2;
    //     pc_2 = -1;
    // end

    //实例化一个测试用的指令存储器
    //instMemery insts(.clk(clk), .pc_1(), .pc_2(), .inst_one(inst_1), .inst_two(inst_2));
    IF if1(.clk(clk), .rst(rst), .pc_1(pc_1), .pc_2(pc_2), .load_over(load_over), .pc_1_out(pc_1_IF), .pc_2_out(pc_2_IF), .inst_1(inst_1), .inst_2(inst_2));

    IF_ID if_id1(.clk(clk), .rst(), .pc_1_in(pc_1_IF), .pc_2_in(pc_2_IF), .inst_1_in(inst_1), .inst_2_in(inst_2), .pc_1_out(pc_1_ID), .pc_2_out(pc_2_ID), .inst_1_out(inst_1_id), .inst_2_out(inst_2_id));

    ID id1(.inst_1(inst_1_id), .inst_2(inst_2_id),
           .reg_rs_1(rs_1), .reg_rt_1(rt_1), .reg_rd_1(rd_1),
           .rob_write_en_1(rob_write_en_1), .rob_write_sel_1(rob_write_sel_1),
           .alu_a_sel_1(alu_a_sel_1), .alu_b_sel_1(alu_b_sel_1), .save_en_1(save_en_1), .work_mode_1(work_mode_1), .alu_ctrl_1(alu_ctrl_1), .complex_ctrl_1(complex_ctrl_1),
           .dm_rd_ctrl_1(dm_rd_ctrl_1), .dm_wr_ctrl_1(dm_wr_ctrl_1), .rob_save_direct_ctrl_1(rob_save_direct_ctrl_1), .imm_out_1(imm_out_1),
           .reg_rs_2(rs_2), .reg_rt_2(rt_2), .reg_rd_2(rd_2),
           .rob_write_en_2(rob_write_en_2), .rob_write_sel_2(rob_write_sel_2),
           .alu_a_sel_2(alu_a_sel_2), .alu_b_sel_2(alu_b_sel_2), .save_en_2(save_en_2), .work_mode_2(work_mode_2), .alu_ctrl_2(alu_ctrl_2), .complex_ctrl_2(complex_ctrl_2),
           .dm_rd_ctrl_2(dm_rd_ctrl_2), .dm_wr_ctrl_2(dm_wr_ctrl_2), .rob_save_direct_ctrl_2(rob_save_direct_ctrl_2), .imm_out_2(imm_out_2));

    OP op1(.clk(clk),
            .rs_1(rs_1), .rt_1(rt_1), .rd_1(rd_1), .rs_2(rs_2), .rt_2(rt_2), .rd_2(rd_2),
            .rob_write_en_1(rob_write_en_1), .rob_write_en_2(rob_write_en_2), .rob_write_sel_1(rob_write_sel_1), .rob_write_sel_2(rob_write_sel_2),
            .rob_save_direct_ctrl_1(rob_save_direct_ctrl_1), .rob_save_direct_ctrl_2(rob_save_direct_ctrl_2),
            .imm_1_in(imm_out_1), .imm_2_in(imm_out_2),
            .save_en_1_in(save_en_1), .save_en_2_in(save_en_2),
            .alu_ctrl_1_in(alu_ctrl_1), .alu_ctrl_2_in(alu_ctrl_2),
            .complex_ctrl_1_in(complex_ctrl_1), .complex_ctrl_2_in(complex_ctrl_2),
            .dm_rd_ctrl_1_in(dm_rd_ctrl_1), .dm_rd_ctrl_2_in(dm_rd_ctrl_2),
            .dm_wr_ctrl_1_in(dm_wr_ctrl_1), .dm_wr_ctrl_2_in(dm_wr_ctrl_2),
            .work_mode_1_in(work_mode_1), .work_mode_2_in(work_mode_2),
            .alu_a_sel_1(alu_a_sel_1), .alu_b_sel_1(alu_b_sel_1), .alu_a_sel_2(alu_a_sel_2), .alu_b_sel_2(alu_b_sel_2),
            .alu_commit_en(), .mul_commit_en(), .div_commit_en(), .mem_commit_en(),
            .alu_commit_rob_no(), .mul_commit_rob_no(), .div_commit_rob_no(), .mem_commit_rob_no(),
            .alu_commit_value(), .mul_commit_value(), .div_commit_value(), .mem_commit_value(),
            .opt_x_1_ready(opt_x_1_ready), .opt_y_1_ready(opt_y_1_ready), .opt_x_2_ready(opt_x_2_ready), .opt_y_2_ready(opt_y_2_ready),
            .opt_x_1_value(opt_x_1_value), .opt_y_1_value(opt_y_1_value), .opt_x_2_value(opt_x_2_value), .opt_y_2_value(opt_y_2_value),
            .opt_x_1_rob(opt_x_1_rob), .opt_y_1_rob(opt_y_1_rob), .opt_x_2_rob(opt_x_2_rob), .opt_y_2_rob(opt_y_2_rob),
            .rs_1_ready(rs_1_ready), .rt_1_ready(rt_1_ready), .rs_2_ready(rs_2_ready), .rt_2_ready(rt_2_ready),
            .rs_1_value(rs_1_value), .rt_1_value(rt_1_value), .rs_2_value(rs_2_value), .rt_2_value(rt_2_value),
            .rd_1_rob_flag(rd_1_rob_flag), .rd_2_rob_flag(rd_2_rob_flag),
            .rs_1_rob(rs_1_rob), .rt_1_rob(rt_1_rob), .rs_2_rob(rs_2_rob), .rt_2_rob(rt_2_rob), .rd_1_rob(rd_1_rob), .rd_2_rob(rd_2_rob),
            .imm_1_out(imm_1_sch), .imm_2_out(imm_2_sch),
            .save_en_1_out(save_en_1_sch), .save_en_2_out(save_en_2_sch),
            .alu_ctrl_1_out(alu_ctrl_1_sch), .alu_ctrl_2_out(alu_ctrl_2_sch),
            .complex_ctrl_1_out(complex_ctrl_1_sch), .complex_ctrl_2_out(complex_ctrl_2_sch),
            .dm_rd_ctrl_1_out(dm_rd_ctrl_1_sch), .dm_rd_ctrl_2_out(dm_rd_ctrl_2_sch),
            .dm_wr_ctrl_1_out(dm_wr_ctrl_1_sch), .dm_wr_ctrl_2_out(dm_wr_ctrl_2_sch),
            .work_mode_1_out(work_mode_1_sch), .work_mode_2_out(work_mode_2_sch));
            
    
    //实例化保留站
    saveStation s1(.clk(clk),
                   .save_en_1(save_en_1_sch), .save_en_2(save_en_2_sch), 
                   .pc_1(pc_1), .pc_2(pc_2),
                   .work_mode_1(work_mode_1_sch), .work_mode_2(work_mode_2_sch),
                   .alu_ctrl_1_sch(alu_ctrl_1_sch), .alu_ctrl_2_sch(alu_ctrl_2_sch), .complex_ctrl_1_sch(complex_ctrl_1_sch), .complex_ctrl_2_sch(complex_ctrl_2_sch),
                   .imm_1(imm_1_sch), .imm_2(imm_2_sch),
                   .rs_1_ready(rs_1_ready), .rt_1_ready(rt_1_ready), .rs_2_ready(rs_2_ready), .rt_2_ready(rt_2_ready),
                   .rs_1_relation(rs_1_rob), .rt_1_relation(rt_1_rob), .rd_1_relation(rd_1_rob),
                   .rs_2_relation(rs_2_rob), .rt_2_relation(rt_2_rob), .rd_2_relation(rd_2_rob),
                   .rd_1_flag(rd_1_rob_flag), .rd_2_flag(rd_2_rob_flag),
                   .rs_1_value(rs_1_value), .rt_1_value(rt_1_value), .rs_2_value(rs_2_value), .rt_2_value(rt_2_value),
                   .dm_rd_ctrl_1(dm_rd_ctrl_1_sch), .dm_rd_ctrl_2(dm_rd_ctrl_2_sch), .dm_wr_ctrl_1(dm_wr_ctrl_1_sch), .dm_wr_ctrl_2(dm_wr_ctrl_2_sch),
                   .alu_commit_en_1(alu_done_1), .alu_commit_en_2(alu_done_2), .mul_commit_en_1(mul_done_1), .mul_commit_en_2(mul_done_2),
                   .alu_commit_value_1(alu_commit_value_1), .alu_commit_value_2(alu_commit_value_2), .mul_commit_value_1(mul_commit_value_1), .mul_commit_value_2(mul_commit_value_2),
                   .alu_commit_save_no_1(alu_commit_save_no_1), .alu_commit_save_no_2(alu_commit_save_no_2), .mul_commit_save_no_1(mul_commit_save_no_1), .mul_commit_save_no_2(mul_commit_save_no_2),
                   .alu_commit_rob_no_1(alu_commit_rob_no_1), .alu_commit_rob_no_2(alu_commit_rob_no_2), .mul_commit_rob_no_1(mul_commit_rob_no_1), .mul_commit_rob_no_2(mul_commit_rob_no_2),
                   .alu_x_1(alu_x_1), .alu_y_1(alu_y_1), .alu_x_2(alu_x_2), .alu_y_2(alu_y_2),
                   .cAlu_ctrl_1(cAlu_ctrl_1), .cAlu_ctrl_2(cAlu_ctrl_2),
                   .alu_ready_en_1(alu_ready_en_1), .alu_ready_en_2(alu_ready_en_2),
                   .alu_save_no_1(alu_save_no_1), .alu_save_no_2(alu_save_no_2), .alu_rob_no_1(alu_rob_no_1), .alu_rob_no_2(alu_rob_no_2),
                   .complex_x_1(complex_x_1), .complex_y_1(complex_y_1), .complex_x_2(complex_x_2), .complex_y_2(complex_y_2),
                   .cComplex_ctrl_1(cComplex_ctrl_1), .cComplex_ctrl_2(cComplex_ctrl_2),
                   .complex_ready_en_1(complex_ready_en_1), .complex_ready_en_2(complex_ready_en_2),
                   .complex_save_no_1(complex_save_no_1), .complex_save_no_2(complex_save_no_2), .complex_rob_no_1(complex_rob_no_1), .complex_rob_no_2(complex_rob_no_2),
                   .address_x_1(address_x_1), .address_y_1(address_y_1), .address_x_2(address_x_2), .address_y_2(address_y_2),
                   .address_ctrl_1(address_ctrl_1), .address_ctrl_2(address_ctrl_2),
                   .address_ready_en_1(address_ready_en_1), .address_ready_en_2(address_ready_en_2),
                   .address_save_no_1(address_save_no_1), .address_save_no_2(address_save_no_2), .address_rob_no_1(), .address_rob_no_2(address_rob_no_2),
                   .mem_address_1(mem_address_1), .mem_content_1(mem_content_1), .mem_address_2(mem_address_2), .mem_content_2(mem_content_2),
                   .mem_rd_ctrl_1(mem_rd_ctrl_1), .mem_rd_ctrl_2(mem_rd_ctrl_2),
                   .mem_wr_ctrl_1(mem_wr_ctrl_1), .mem_wr_ctrl_2(mem_wr_ctrl_2),
                   .mem_read_en_1(mem_read_en_1), .mem_write_en_1(mem_write_en_1), .mem_read_en_2(mem_read_en_2), .mem_write_en_2(mem_write_en_2),
                   .mem_save_no_1(mem_save_no_1), .mem_save_no_2(mem_save_no_2), .mem_rob_no_1(mem_rob_no_1), .mem_rob_no_2(mem_rob_no_2));


    //普通运算器实例化
    commonAlu cAlu1(.clk(clk), .rst(), .data_ready(alu_ready_en_1), .x(alu_x_1), .y(alu_y_1), .ctrl(cAlu_ctrl_1), .save_no_in(alu_save_no_1), .rd_rob_in(alu_rob_no_1), .done(alu_done_1), .save_no_out(alu_commit_save_no_1), .rd_rob_out(alu_commit_rob_no_1), .result(alu_commit_value_1));

    //普通运算器实例化
    commonAlu cAlu2(.clk(clk), .rst(), .data_ready(alu_ready_en_2), .x(alu_x_2), .y(alu_y_2), .ctrl(cAlu_ctrl_2), .save_no_in(alu_save_no_2), .rd_rob_in(alu_rob_no_2), .done(alu_done_2), .save_no_out(alu_commit_save_no_2), .rd_rob_out(alu_commit_rob_no_2), .result(alu_commit_value_2));

    //乘法器实例化
    wallace mul1(.clk(clk), .rst(), .data_ready(complex_ready_en_1), .x(complex_x_1), .y(complex_y_1), .ctrl(complex_ctrl_1), .save_no_in(complex_save_no_1), .rd_rob_in(complex_rob_no_1), .done(mul_done_1), .save_no_out(mul_commit_save_no_1), .rd_rob_out(mul_commit_rob_no_1), .result(mul_commit_value_1));

    //乘法器实例化
    wallace mul2(.clk(clk), .rst(), .data_ready(complex_ready_en_2), .x(complex_x_2), .y(complex_y_2), .ctrl(complex_ctrl_2), .save_no_in(complex_save_no_2), .rd_rob_in(complex_rob_no_2), .done(mul_done_2), .save_no_out(mul_commit_save_no_2), .rd_rob_out(mul_commit_rob_no_2), .result(mul_commit_value_2));
endmodule